# gradio 和软件连接的中间业务层

import os
import queue

import numpy as np
import pandas as pd
import json
import gradio as gr
import datetime
from processing.Spectrum_calibration import SpectrumCalibration

class fpga_data:
    def __init__(self,count,fpga_signal,angle:float,wavelength:float):
        self.count = count
        self.fpga_signal = fpga_signal
        self.angle = angle
        self.wavelength = wavelength


#fpga图像的绘制图像类
class PltFpga:
    def __init__(self):
        self.count = 0#信号计数
        # 创建消息队列
        self.fpga_list = []
        self.x = []
        self.y = []
        self.sc = SpectrumCalibration()

    #清空渲染列表
    def del_fpgalist(self):
        self.count = 0
        self.fpga_list=[]
        return self.get_gradio_plot()

    #硬件传来的数据传入使用此函数，调用此函数的得开多线程组建消费者线程
    def add_fpga_data(self, data, angle, wavelength):
        fpga_data_obj = fpga_data(self.count,data,angle,wavelength)
        self.count = self.count+1
        self.fpga_list.append(fpga_data_obj)

    # 保存当前数据为JSON文件:count,fpga_signal,angle:float,wavelengths:float
    def save_to_json(self):
        if len(self.fpga_list)>0:
            data_directory = 'data'  # 指定目录名称
            if not os.path.exists(data_directory):
                os.makedirs(data_directory)  # 如果目录不存在，创建它
            current_datetime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
            # 将 fpga_data 对象列表转换为字典列表
            dict_list = [{"count": obj.count, "fpga_signal": obj.fpga_signal, "angle":obj.angle, "wavelength":obj.wavelength} for obj in self.fpga_list]
            full_path = os.path.join(data_directory, f'{current_datetime}.json')
            with open(full_path, 'w') as file:
                json.dump(dict_list, file)

    # 加载JSON文件为数据
    def load_from_json(self,filename):
        with open(filename, 'r') as file:
            data = json.load(file)
            # 转换数据为 fpga_data 对象列表
            fpga_list = [fpga_data(item['count'], item['fpga_signal'],item['angle'],item['wavelength']) for item in data]
            return fpga_list

    def fix_x_y(self):
        self.sc.input_data(self.y)
        self.sc.deal_data()
        self.y = self.sc.y
        self.sc.clear_data()

    def adjust_array(self, arr):
        if len(arr) > 500:
            return arr[:500]
        elif len(arr) < 500:
            return arr + [0] * (500 - len(arr))
        else:
            return arr

    #从json转为plot
    def json_to_plot(self,file):
        #file = f"./data/{file}.json"
        #print(file)
        load_fpga_list = self.load_from_json(file)
        self.x.clear()
        self.y.clear()
        for data in load_fpga_list:
            self.x.append(data.wavelength)  # 提取 count 属性并添加到 x 列表
            self.y.append(data.fpga_signal)  # 提取 data 属性并添加到 y 列表
        self.fix_x_y()
        df = pd.DataFrame({
            'times': self.x,
            'fpga_signal': self.y
            })
        update = gr.LinePlot(
            value=df,
            x="times",
            y="fpga_signal",
            title="光谱数据",
            width=600,
            height=350,
        )
        #print(self.y)
        return update


    #gradio的图像函数
    def get_gradio_plot(self):
        self.x=[]
        self.y=[]
        for data in self.fpga_list:
            self.x.append(data.wavelength)  # 提取 count 属性并添加到 x 列表
            self.y.append(data.fpga_signal)  # 提取 data 属性并添加到 y 列表
        print(f"当前队列x:{len(self.x)},y:{len(self.y)}")
        if(len(self.x)!=500):
            self.x = self.adjust_array(self.x)
        if (len(self.y) != 500):
            self.y = self.adjust_array(self.y)
        #这儿把x和y全部先丢进波长标定里，输出正确的x,y（x波长，y光强）
        self.fix_x_y()
        df = pd.DataFrame({
            'times': self.x,
            'fpga_signal': self.y
            })
        update = gr.LinePlot(
                    value=df,
                    x="times",
                    y="fpga_signal",
                    title="光谱数据",
                    width=600,
                    height=350,
                )
        return update

